package com.sinog.biz.schedule;

import com.sinog.biz.mapper.havexml.DepartmentMapper;
import com.sinog.biz.mapper.havexml.other.AzbjRsMapper;
import com.sinog.biz.mapper.havexml.other.UserLoginDetailsMapper;
import com.sinog.biz.schedule.async.AsyncSql;
import com.sinog.biz.util.CodeUrlUtils;
import com.sinog.biz.util.WorkDayUtil;
import com.sinog.core.domain.Department;
import com.sinog.core.domain.UserLoginDetails;
import com.sinog.core.utilbean.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @desc 定时任务：首页相关统计数据定时任务，首页各项统计指标 任务1：每25分钟执行一次 任务2：每天凌晨2点55
 * @author lzq
 * @date 2021-09-20 00:02
 */
@Slf4j
@Component
@Configuration
@ConditionalOnProperty(name = "gkzx.azbj.sy.open", havingValue = "true")
public class HomePageSchedule {

    @Autowired
    private AsyncSql asyncSql;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private AzbjRsMapper azbjRsMapper;
    @Autowired
    private UserLoginDetailsMapper userLoginDetailsMapper;

    /**
     * 任务1：首页小卡片相关统计数据定时任务
     */
    @Scheduled(cron = "${gkzx.azbj.sy.cron}")
    @Async
    public void selectAzbjByDepartId() {
        //解决如果列表处理数据后数量变为0，但是小卡片还是显示之前的数量问题
        azbjRsMapper.setCountIsZero();
        //------首页地图使用数据--------
        //司法厅---全部帮教对象
        asyncSql.sftbjdxrs();
        //司法厅---重点帮教对象
        asyncSql.sftzdbjdxrs();
        //司法厅---未衔接
        asyncSql.sftwxjrs();
        //司法厅---失联
        asyncSql.sftslrs();
        //地市司法局---全部帮教对象
        asyncSql.dssfjbjdxrs();
        //地市司法局---重点帮教对象
        asyncSql.dssfjzdbjdxrs();
        //地市司法局---未衔接
        asyncSql.dssfjwxjrs();
        //地市司法局---失联
        asyncSql.dssfjslrs();
        //区县司法局---全部帮教对象
        asyncSql.qxsfjbjdxrs();
        //区县司法局---重点帮教对象
        asyncSql.qxsfjzdbjdxrs();
        //区县司法局---未衔接
        asyncSql.qxsfjwxjrs();
        //区县司法局---失联
        asyncSql.qxsfjslrs();
        //--------首页小方块使用数据--------------
        //司法所---未衔接人数
        asyncSql.jdwxjrs();
        //司法所--失联人数
        asyncSql.slrs();
        //监狱---待衔接重点帮教对象人数
        asyncSql.dxjzddxrs();
        //监狱---待衔接人数
        asyncSql.dxjrs();
        //监狱---监狱未衔接人数
        asyncSql.jywxjrs();
        //监狱---核查失败人数
        asyncSql.hcsbrs();
        //监狱---未进行出监、危险性评估人数
        asyncSql.wpgrs();
        //监狱---待核查人数
        asyncSql.dhcrs();
        log.info("------定时任务执行完毕------");
    }

    /**
     * 任务2：定时检查rs表是否有初始化值，没有则初始化，对于新增的部门初始化初始值
     */
    @Scheduled(cron = "${gkzx.azbj.rs.save}")
    @Async
    public void executeAzbjrsSave() {
        // 本地code编码
        String localCode = CodeUrlUtils.getLocalCode();
         // 公安厅code编码 code:200000
         String gatCode = CodeUrlUtils.getGatCode();
         // 假如获取的是 410100,410200
         StringBuffer buffer = new StringBuffer("$");
         getparent(localCode,buffer);
         String gatCodes = getparent(gatCode,buffer);
         String[] departId = gatCodes.split(",");
         for(String depart : departId) {
             if("$".equalsIgnoreCase(depart) || "".equalsIgnoreCase(depart)) {
                 continue;
             }
             // 查询azbj_rs表是否存在此机构,如果不存在则增加
             Integer num = azbjRsMapper.selectCount(depart);
             if(Constants.Number.NUM_ZERO >= num) {
                 ArrayList<String> items = new ArrayList<>(16);
                 //帮教对象人数
                 items.add("bjdxrs");
                 //重点帮教对象人数
                 items.add("zdbjdxrs");
                 //未衔接人数
                 items.add("wxjrs");
                 //失联人数
                 items.add("slrs");
                 //待衔接重点帮教对象人数
                 items.add("dxjzddxrs");
                 //待衔接人数
                 items.add("dxjrs");
                 //核查失败人数
                 items.add("hcsbrs");
                 //未进行出监、危险性评估人数
                 items.add("wpgrs");
                 //待核查人数
                 items.add("dhcrs");
                 for(String item : items) {
                     azbjRsMapper.saveAzbjRs(depart,item);
                 }
             }
         }
        //将统计项放入redis中
        //数据指标统计
        asyncSql.census(localCode.substring(0,2));
        //统计分析报表
        asyncSql.bbCensus(localCode.substring(0,2));
        // updateWorkDay();
    }

    /**
     * 获取所有部门子集
     * @param localCode 本地编码
     * @param buffer buffer
     * @return String
     */
    private String getparent(String localCode,StringBuffer buffer) {
        List<Department> departments = departmentMapper.searchCodeList(localCode);
        for (Department department : departments) {
            String id = department.getId();
            buffer.append(",").append(id);
            getparent(id,buffer);
        }
        return buffer.toString();
    }

    /**
     * 每天定时更新数据库中的user_login_details表中的workday字段
     * 先查询表中的workday字段是否为空，如果为空，则进行判断是否工作日，然后进行更新，否则不进行任何操作
     */
    private void updateWorkDay() {
        List<UserLoginDetails> userLoginDetails = userLoginDetailsMapper.selectWorkDayIsNull();
        if(Constants.Number.NUM_ZERO != userLoginDetails.size()) {
            for(UserLoginDetails u : userLoginDetails) {
                Date loginTime = u.getLoginTime();
                if(null != loginTime) {
                    String yearMonth = new SimpleDateFormat("yyyy-MM").format(loginTime);
                    boolean workDay = WorkDayUtil.isWorkDay(yearMonth);
                    u.setWorkday(workDay ? "1" : "2");
                }
            }
            userLoginDetailsMapper.batchUpdateWorkDay(userLoginDetails);
        }
    }
}